package com.stox.downloader;

import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.Timer;
import java.util.TimerTask;

import com.stox.core.manager.BarManager;
import com.stox.core.manager.ExchangeManager;
import com.stox.core.model.Exchange;
import com.stox.core.ui.swing.widget.MainFrame;
import com.stox.core.util.Constant;
import com.stox.design.AfterUiInitializable;
import com.stox.downloader.bse.BseDataProvider;
import com.stox.ioc.Container;
import com.stox.resources.i18n.MessageSource;


public class DownloadManager implements AfterUiInitializable<Void, Void>{

	private boolean running;
	private boolean cancelRequested = false;
	Timer timer = new Timer();
	TimerTask timerTask = new TimerTask(){
		@Override
		public void run() {
			download();
		}
	};
	
	/*
	 * TODO Currently configuring only for BSE, should be enhanced to use Yahoo, Google
	 */
	private BseDataProvider bseDataProvider;
	private BarManager barManager;
	private ExchangeManager exchangeManager;
	
	public DownloadManager() {
		this.bseDataProvider = Container.get(BseDataProvider.class);
		this.barManager = Container.get(BarManager.class);
		this.exchangeManager = Container.get(ExchangeManager.class);
	}
	
	
	@Override
	public int getOrder() {
		return Integer.MAX_VALUE;
	}
	
	@Override
	public Void invoke(Void payload) {
		timer.schedule(timerTask, 0, 1000*60);
		return null;
	}
	
	@Override
	public boolean isInitialized() {
		return true;
	}
	
	public void download(){
		List<Exchange> exchanges = exchangeManager.getConfiguredExchanges();
		if(exchanges != null && !exchanges.isEmpty()){
			for(Exchange exchange : exchanges){
				bredthDownload(exchange);
			}
		}
		MainFrame.getInstance().getMessagePanel().setMessage("");
	}
	
	public void bredthDownload(final Exchange exchange){
		if(!running){
			running = true;
			try{
				final Calendar calendar = Calendar.getInstance();
				calendar.setTime(exchange.getLastTradingDate());
				Date endDate = new Date();
				while(!calendar.getTime().after(endDate)){
					try{
						if(isCancelRequested()){
							running = false;
							return;
						}
						calendar.add(Calendar.DATE, 1);
						
						if(Calendar.SUNDAY == calendar.get(Calendar.DAY_OF_WEEK) 
								|| Calendar.SATURDAY == calendar.get(Calendar.DAY_OF_WEEK)){
							continue;
						}
						
						MainFrame.getInstance().getMessagePanel().setMessage(
								MessageSource.getMessage("Downloading.data.for.date.exchange", 
										Constant.dateFormat.format(calendar.getTime()), exchange.getName()));
						DataStream dataStream = bseDataProvider.get(exchange, calendar.getTime());
						if(isCancelRequested()){
							running = false;
							return;
						}
						if(dataStream != null && dataStream.getBarList() != null 
								&& !dataStream.getBarList().isEmpty()){
							barManager.persist(dataStream.getBarList());
							exchangeManager.updateLastTradingDate(exchange.getCode(), calendar.getTime());
						}
					}catch(Throwable t){
						t.printStackTrace();
					}
				}
			}finally{
				running = false;
			}
		}
	}
	
	public boolean isRunning() {
		return running;
	}
	
	public boolean isCancelRequested() {
		return cancelRequested;
	}
	
	public void cancel(){
		cancelRequested = true;
		timer.cancel();
		timerTask.cancel();
		while(running){
			Thread.yield();
		}
	}
}
